package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import logic.NodeFactory;
import logic.PreferenceEnum;
import logic.PreferenceFactory;
import logic.Property;
import misc.Constants;
import misc.Env;
import misc.Mail;
import misc.ShellEnv;

import org.apache.commons.beanutils.PropertyUtils;

import domain.Node;
import domain.NodeManager;
import domain.PreferenceManager;
import domain.Share;
import domain.StackHolder;
import domain.StorageNode;





/**
 * Servlet implementation class for Servlet: ActionServlet
 *
 */
 public class ActionServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
	 
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public ActionServlet() {
		super();
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void init() throws ServletException {

		getServletContext().setAttribute("concurrentProcess", new Boolean(false));
		// Scan the network for shares.
		scan();
	}
	
	@Override
	public void destroy() {

		PreferenceManager preferenceManager;
		NodeManager nodeManager;
		
		preferenceManager = (PreferenceManager) getServletContext().getAttribute("preferenceManager");
		nodeManager = (NodeManager) getServletContext().getAttribute("nodeManager");
		
		// Unmount and remove all backup nodes.
		for (Node node : preferenceManager.getBackupNodes()) {
			node.removeAllShares(preferenceManager.getStorageServer().getBackupsMountPoint());
		}
		
		// Unmount and remove all client nodes.
		for (Node node : nodeManager.getNodes()) {
			node.removeAllShares(preferenceManager.getStorageServer().getClientsMountPoint());
		}
		
		super.destroy();
	}
	
	@Override
	protected void doPost(HttpServletRequest arg0, 
			HttpServletResponse arg1) throws ServletException, IOException {
		
		doGet(arg0, arg1);
	}
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, 
			HttpServletResponse response) throws ServletException, IOException {
		
		RequestDispatcher requestDispatcher;
		ServletContext servletContext = getServletContext();
		boolean concurrentProcess = false;
		boolean doBackup = false;
		
		if (servletContext.getAttribute("concurrentProcess") != null) {
			if ((Boolean) servletContext.getAttribute("concurrentProcess")) {
				concurrentProcess = true;
			}
		}
		
		if (!concurrentProcess) {
			if (request.getParameter("action") != null) {
				
				if (request.getParameter("action").equals("removeHost") ||
					request.getParameter("action").equals("removeShare")) {
				
					if (request.getParameter("action").equals("removeHost")) {
						removeHost((NodeManager) servletContext.getAttribute("nodeManager"), 
								(String) request.getParameter("hostName"));
						
					} else if (request.getParameter("action").equals("removeShare")) {
						removeShare((NodeManager) servletContext.getAttribute("nodeManager"), 
								(String) request.getParameter("hostName"), 
								(String) request.getParameter("shareName"));
					}				
					
					// Write file of application context data
					writeNodes(servletContext.getRealPath(Constants.NODESSDATANAME), 
							(NodeManager) getServletContext().getAttribute("nodeManager"));
				
				} else if (request.getParameter("action").equals("refreshPreferences")) {
					
					// Update preference manager
					for (Object obj : request.getParameterMap().keySet()) {

						if (obj instanceof String && ((String) obj).startsWith("preferenceManager")) {
							
							try {
								PropertyUtils.setNestedProperty(servletContext.getAttribute("preferenceManager"), 
										((String) obj).replaceAll("preferenceManager.", ""),
										request.getParameter((String) obj));
							
							} catch (IllegalAccessException e) {
								e.printStackTrace();
							
							} catch (InvocationTargetException e) {
								e.printStackTrace();
							
							} catch (NoSuchMethodException e) {
								e.printStackTrace();
							}
						}
					}
					
					// Write new preferences
					writePreferences(servletContext.getRealPath(Constants.PREFERENCESDATANAME),
							(PreferenceManager) getServletContext().getAttribute("preferenceManager"));
					
				} else if (request.getParameter("action").equals("mountShare")) {
					mountShares((NodeManager) servletContext.getAttribute("nodeManager"), 
							(String) request.getParameter("hostname"), (String) request.getParameter("sharename"),
							(String) request.getParameter("username"), (String) request.getParameter("password"));
					
					// Write file of application context data
					writeNodes(servletContext.getRealPath(Constants.NODESSDATANAME), 
							(NodeManager) getServletContext().getAttribute("nodeManager"));
					
				} else if (request.getParameter("action").equals("searchShare")) {
					searchShares((NodeManager) servletContext.getAttribute("nodeManager"), 
							(String) request.getParameter("hostname"), (String) request.getParameter("username"), 
							(String) request.getParameter("password"), true);
					
					// Write file of application context data
					writeNodes(servletContext.getRealPath(Constants.NODESSDATANAME), 
							(NodeManager) getServletContext().getAttribute("nodeManager"));
					
				} else if (request.getParameter("action").equals("scan")) {
					servletContext.setAttribute("concurrentProcess", new Boolean(true));
					scan();
					servletContext.setAttribute("concurrentProcess", new Boolean(false));
					
				} else if (request.getParameter("action").equals("backup")) {
					servletContext.setAttribute("concurrentProcess", new Boolean(true));
					doBackup = true;
					// Do the backup.
					doBackup(servletContext.getRealPath(Constants.BACKUP_SHELLSCRIPT), 
							servletContext.getRealPath(Constants.BACKUP_REPORT_DIRECTORY));
					
					// Send information about the backup.
					sendBackUpReportMail();
					servletContext.setAttribute("concurrentProcess", new Boolean(false));
					
				}
			}
			requestDispatcher = request.getRequestDispatcher("index.jsp");
			requestDispatcher.forward(request, response);		
		} else {
			if (doBackup) {
				requestDispatcher = request.getRequestDispatcher("backup.jsp");
				requestDispatcher.forward(request, response);
			} else {
				requestDispatcher = request.getRequestDispatcher("index.jsp");
				requestDispatcher.forward(request, response);
			}

		}
	}
	
	private void sendBackUpReportMail() {
		
	}
	
	@SuppressWarnings("unchecked")
	private void writeNodes(String filename, ArrayList<Node> nodes, PreferenceManager preferenceManager) {
	
		StringBuffer buffer;
		Share share;
		String ip, sharename;
		ArrayList<Share> shareList;
		
		PrintWriter pw = null;
		buffer = new StringBuffer();			
		buffer.append(Constants.XMLHEADER);
		buffer.append(Constants.NODESBEGIN);
		
		if (!nodes.isEmpty()) {		
			
			for (Node node : nodes) {
				shareList = node.getShares();
				ip = node.getIpAddress();
				buffer.append("<node name=\"");
				buffer.append(node.getName());
				buffer.append("\" ipaddress=\"");
				buffer.append(ip);
				buffer.append("\" username=\"");
				
				if (node.getUsername() != null) {
					buffer.append(node.getUsername());
				}
				buffer.append("\" password=\"");
				
				if (node.getPassword() != null) {
					buffer.append(node.getPassword());
				}
				buffer.append("\">");
				buffer.append(Constants.SHARESBEGIN);
				
				for (int i=0; i<shareList.size(); i++) {
					share = shareList.get(i);
					sharename = share.getName();
					
					if (preferenceManager.getBackupNodes() != null) {
						
						for (Node backu0Node : preferenceManager.getBackupNodes()) {
							
							if (backu0Node.getShares() != null) {
								
								for (Share tempshare : backu0Node.getShares()) {
									
									// Prevent storing backup node's share.
									if ((backu0Node.getName().equals(node.getName()) && tempshare.getName() != null && !tempshare.getName().equals(sharename)) ||
											(!backu0Node.getName().equals(node.getName()))) {
										
										buffer.append("<share name=\"");
										buffer.append(sharename);
										buffer.append("\" username=\"");
				
										if (share.getUsername() != null) {
											buffer.append(share.getUsername());
										}
										buffer.append("\" password=\"");
										
										if (share.getPassword() != null) {
											buffer.append(share.getPassword());
										}
;										buffer.append("\"/>");
									}
								}
							}	
						}
					}
				}
				buffer.append(Constants.SHARESEND);
				buffer.append(Constants.NODEEND);
			}
			buffer.append(Constants.NODESEND);
			
			try {
				pw = new PrintWriter(filename);
				pw.println(buffer.toString());	
			
			} catch (Exception ex) {
			
			} finally {
				pw.flush();
				pw.close();
			}
		}			
	}
	
	private void writeNodes(String filename, NodeManager nodeManager) {
		
		StringBuffer buffer;
		PrintWriter pw;
		
		pw = null;
		buffer = new StringBuffer();
		
		buffer.append(Constants.XMLHEADER);
		buffer.append(Constants.NODESBEGIN);
		
		for (Node node : nodeManager.getNodes()) {
			
			buffer.append("<node name=\"");
			buffer.append(node.getName());
			buffer.append("\" ipaddress=\"");
			buffer.append(node.getIpAddress());
			buffer.append("\" username=\"");
			
			if (node.getUsername() != null) {
				buffer.append(node.getUsername());
			}
			
			buffer.append("\" password=\"");
			if (node.getPassword() != null) {
				buffer.append(node.getPassword());
			}
			buffer.append("\">");
			buffer.append(Constants.SHARESBEGIN);
			
			for (Share share : node.getShares()) {
				buffer.append("<share name=\"");
				buffer.append(share.getName());
				buffer.append("\" username=\"");
				
				if (share.getUsername() != null) {
					buffer.append(share.getUsername());
				}
				buffer.append("\" password=\"");
				
				if (share.getPassword() != null) {
					buffer.append(share.getPassword());
				}
;				buffer.append("\"/>");
			}
			buffer.append(Constants.SHARESEND);
			buffer.append(Constants.NODEEND);
		}
		buffer.append(Constants.NODESEND);
		
		try {
			pw = new PrintWriter(filename);
			pw.println(buffer.toString());	
		
		} catch (Exception ex) {
		
		} finally {
			pw.flush();
			pw.close();
		}
	}
	
	private void writePreferences(String filename, PreferenceManager preferenceManager) {
		
		StringBuffer buffer;
		PrintWriter pw;
		
		pw = null;
		buffer = new StringBuffer();
		
		buffer.append(Constants.XMLHEADER);
		buffer.append(Constants.PREFERENCESBEGIN);
		buffer.append(Constants.STORAGENODEBEGIN);
		buffer.append("<ip>" + preferenceManager.getStorageServer().getIpAddress() + "</ip>");
		buffer.append("<os>Linux Schiller 2.6.17.6</os>");
		buffer.append("<clientsMountPoint>" + preferenceManager.getStorageServer().getClientsMountPoint() + "</clientsMountPoint>");
		buffer.append("<backupsMountPoint>" + preferenceManager.getStorageServer().getBackupsMountPoint() + "</backupsMountPoint>");
		buffer.append(Constants.STORAGENODEEND);
		buffer.append("<sender emailaddress=\"" + preferenceManager.getSender().getEmailAddress() + "\" smtpserver=\"" + preferenceManager.getSender().getSMTPServer() + "\" emailusername=\"" + preferenceManager.getSender().getEmailUsername() + "\" emailpassword=\"" + preferenceManager.getSender().getEmailPassword() + "\"/>");
		buffer.append("<recipient emailaddress=\"" + preferenceManager.getRecipient().getEmailAddress() + "\"/>");
		buffer.append("<backupnode name=\"" + preferenceManager.getBackupNodes().get(0).getName() + "\" ipaddress=\"" + preferenceManager.getBackupNodes().get(0).getIpAddress() + "\">");
		
		buffer.append(Constants.SHARESBEGIN);
		
		for (Share share : (preferenceManager.getBackupNodes().get(0).getShares())) {
			buffer.append("<share name=\"");
			buffer.append(share.getName());
			buffer.append("\" username=\"");
			
			if (share.getUsername() != null) {
				buffer.append(share.getUsername());
			}
			buffer.append("\" password=\"");
			
			if (share.getPassword() != null) {
				buffer.append(share.getPassword());
			}
				buffer.append("\"/>");
		}
		buffer.append(Constants.SHARESEND);
		buffer.append(Constants.BACKUPNODEEND);
		buffer.append(Constants.PREFERENCESEND);
		
		try {
			pw = new PrintWriter(filename);
			pw.println(buffer.toString());	
		
		} catch (Exception ex) {
		
		} finally {
			pw.flush();
			pw.close();
		}
		
	}
	
	@SuppressWarnings("unchecked")
	private void syncShares(NodeManager nodeManager, ArrayList<Node> nodes) {
		boolean addNode, addShare, nodefound, sharefound;
		
		// add nodes and shares to nodeManager
		for (Node node : nodes) {
			addNode = true;
			ArrayList<Node> saveNodes = (ArrayList<Node>) nodeManager.getNodes().clone();
			
			for (Node savedNode : saveNodes) {
			
				// check whether node already exicts in nodeManager
				if ((node.getName().equalsIgnoreCase(savedNode.getName())) && 
					(node.getIpAddress().equalsIgnoreCase(savedNode.getIpAddress())))	{
					
					addNode = false;
					
					// node already exists in nodeManager --> sync shares
					for (Share share : node.getShares()) {
						addShare = true;
						ArrayList<Share> savedShares = (ArrayList<Share>) savedNode.getShares().clone();
						
						for (Share savedShare : savedShares) {
							
							if (share.getName().equalsIgnoreCase(savedShare.getName())) {
								addShare = false;
							}	
						}
						
						if (addShare) {
							savedNode.addShare(share);
						}
					}
				}
						
			}
			
			if (addNode) {
		 		// add node to nodeManager
				nodeManager.addNode(node);
			}
		}
		
		ArrayList<Node> saveNodes = (ArrayList<Node>) nodeManager.getNodes().clone();
		
		// remove non-available nodes and shares from nodeManager
		for (Node savedNode : saveNodes) {
			nodefound = false;
			
			for (Node node : nodes) {
				
				if ((node.getName().equalsIgnoreCase(savedNode.getName())) && 
						(node.getIpAddress().equalsIgnoreCase(savedNode.getIpAddress())))	{
					nodefound = true;
					ArrayList<Share> savedShares = (ArrayList<Share>) savedNode.getShares().clone();
					
					for (Share savedShare : savedShares) {
						sharefound = false;
						
						for (Share share : node.getShares()) {
						
							if (share.getName().equalsIgnoreCase(savedShare.getName())) {
								sharefound = true;
							}	
						}
						
						if (!sharefound) {
							savedNode.removeShare(savedShare.getName());
						}
					}
				}
			}
			
			if (!nodefound) {
				nodeManager.removeNode(savedNode.getName());	
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private void checkForShares(NodeManager nodeManager, NodeManager nodeManager2) {
		
		ArrayList<Node> nodes = (ArrayList<Node>) nodeManager.getNodes().clone();
		ArrayList<Share> shares;
		ArrayList<Share> existingShares;
		
		for (Node node : nodes) {
			
			if ((node.getUsername() != null) && (node.getPassword() != null)) {
				
				if ((!node.getUsername().equals("")) && (node.getShares().size() == 0)) {
					shares = node.searchShare();
					
					if (nodeManager2.getNode(node.getName()) != null) {
						
						existingShares = nodeManager2.getNode(node.getName()).getShares();
						for (Share share : shares) {
							
							for (Share existingShare : existingShares) {
								
								if (share.getName().equalsIgnoreCase(existingShare.getName())) {
									nodeManager.getNode(node.getName()).addShare(existingShare);
								}
							}
						}	
					}
				}
			}
		}
	}
	
	private void removeHost(NodeManager nodeManager, String hostName) {
		nodeManager.removeNode(hostName);
	}
	
	private void removeShare(NodeManager nodeManager, String hostName, String shareName) {
		
		Node host = nodeManager.getNode(hostName);
		Share share = new Share(shareName);
		
		if (host != null) {
			host.removeShare(shareName);
			share.unmountShare(nodeManager.getMountPoint(), hostName);
			share.removeMountPoint(nodeManager.getMountPoint(), hostName);
			
		} else {
			System.out.println("No host with hostName: " + hostName);
		}
	}
	
	private void mountShares(NodeManager nodeManager, String hostName, String shareName, String username, String password) {
		
		Node node = nodeManager.getNode(hostName);
		
		if (node != null) {
			
			for (Share share : node.getShares()) {
				
				if (share.getName().equalsIgnoreCase(shareName)) {
					share.setUsername(username);
					share.setPassword(password);
					share.mountShare(nodeManager.getMountPoint(), hostName);
					return;
				}
			}
			
		}
	}
	
	private void searchShares(NodeManager nodeManager, String hostname, String username, String password, boolean mountShares) {
		
		ArrayList<Share> shares;
		Node node = nodeManager.getNode(hostname);
		
		if (node != null) {
			node.setUsername(username);
			node.setPassword(password);
			shares = node.searchShare();
			
			// add shares to host
			node.setShares(shares);

			if (mountShares) {
				
				// try to mount shares
				for(Share share : shares) {
					
					if (share.mountShare(nodeManager.getMountPoint(), hostname)) {
						share.setUsername(username);
						share.setPassword(password);
					}
				}		
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	private void scan() {
		
		ArrayList<Node> hosts;
		HashMap<String, Object> objects;
		ArrayList<Node> nodes;
		Property propertyPreferences, hostPreferences;
		PreferenceManager preferenceManager;
		NodeManager nodeManager, nodeManager2;
		ServletContext servletContext;

		nodeManager = null;
		nodeManager2 = null;
		preferenceManager = null;
		nodes = null;
		servletContext = getServletContext();
		
		propertyPreferences = new Property();
		propertyPreferences.addProperty("xmlSchemaUri", servletContext.getRealPath(Constants.PREFERENCESSCHEMANAME));
		propertyPreferences.addProperty("xmlHandler", "PreferencesHandler");
		
		hostPreferences = new Property();
		hostPreferences.addProperty("xmlSchemaUri", servletContext.getRealPath(Constants.NODESSSCHEMANAME));
		hostPreferences.addProperty("xmlHandler", "HostHandler");

		NodeFactory hostFactory = new NodeFactory(hostPreferences);
		servletContext = getServletContext();
		
		propertyPreferences = new Property();
		propertyPreferences.addProperty("xmlSchemaUri", servletContext.getRealPath(Constants.PREFERENCESSCHEMANAME));
		propertyPreferences.addProperty("xmlHandler", "PreferencesHandler");
		
		hostPreferences = new Property();
		hostPreferences.addProperty("xmlSchemaUri", servletContext.getRealPath(Constants.NODESSSCHEMANAME));
		hostPreferences.addProperty("xmlHandler", "HostHandler");
		
		PreferenceFactory preferencesFactory = new PreferenceFactory(propertyPreferences);
			
		try {
			
			if (preferencesFactory.validate(servletContext.getRealPath(Constants.PREFERENCESDATANAME))) {
				preferencesFactory.parse(servletContext.getRealPath(Constants.PREFERENCESDATANAME));
				
				// Initialize the preference manager.
				preferenceManager = new PreferenceManager(
						(StorageNode) preferencesFactory.getObjects().get(PreferenceEnum.StorageNode.name()),
						(StackHolder) preferencesFactory.getObjects().get(PreferenceEnum.Recipient.name()),
						(StackHolder) preferencesFactory.getObjects().get(PreferenceEnum.Sender.name()),
						(ArrayList<Node>) preferencesFactory.getObjects().get(PreferenceEnum.BackUpNode.name()));
				
				// Connect the preference Manager to the backupshares.
				preferenceManager.connectBackupNodes();
			}

			// Initialize nodeManager with existing hosts stored in xml file
			if (hostFactory.validate(servletContext.getRealPath(Constants.NODESSDATANAME))) {
				hostFactory.parse(servletContext.getRealPath(Constants.NODESSDATANAME));
				objects = hostFactory.getObjects();
				hosts = new ArrayList<Node>();
	
				for (Object obj1 : objects.keySet()) {
					hosts.add((Node) objects.get(obj1));
				}
				nodeManager = new NodeManager(preferenceManager.getStorageServer().getClientsMountPoint(), hosts);
			}
						
			// Scan the network for nodes.
			nodes = hostFactory.scan();
	
			if (nodeManager != null) {
				
				// synchronize nodes
				syncShares(nodeManager, nodes);
				
				if (hostFactory.validate(servletContext.getRealPath(Constants.NODESSDATANAME))) {
					hostFactory.parse(servletContext.getRealPath(Constants.NODESSDATANAME));
					objects = hostFactory.getObjects();
					hosts = new ArrayList<Node>();
	
					for (Object obj1 : objects.keySet()) {
						hosts.add((Node) objects.get(obj1));
					}
					nodeManager2 = new NodeManager(preferenceManager.getStorageServer().getClientsMountPoint(), hosts);
				}
				
				// if nodeManager contains nodes with an username+password but with no shares, search for shares by providing the username+password
				checkForShares(nodeManager, nodeManager2);
				// Write the shares into the configuration file.
				writeNodes(servletContext.getRealPath(Constants.NODESSDATANAME), nodeManager.getNodes(), preferenceManager);
			
			} else {
				
				// Write the shares into the configuration file.
				writeNodes(servletContext.getRealPath(Constants.NODESSDATANAME), nodes, preferenceManager);
				
				if (hostFactory.validate(servletContext.getRealPath(Constants.NODESSDATANAME))) {
					hostFactory.parse(servletContext.getRealPath(Constants.NODESSDATANAME));
					objects = hostFactory.getObjects();
					hosts = new ArrayList<Node>();
	
					for (Object obj1 : objects.keySet()) {
						hosts.add((Node) objects.get(obj1));
					}
					nodeManager = new NodeManager(preferenceManager.getStorageServer().getClientsMountPoint(), hosts);
				}	
			}
			
			nodeManager.mountAllShares();
			
		} catch (Exception ex) {
			ex.printStackTrace();
		
		}
	
		if (nodeManager.getNodes().size() > 0) {
			
			if (nodeManager != null && preferenceManager != null) {
				getServletContext().setAttribute("nodeManager", nodeManager);
				getServletContext().setAttribute("preferenceManager", preferenceManager);
			}
			
			// Send initialization mail.
			sendStartUpMail();
		}
	}
	
	private void sendStartUpMail() {
		
		StringBuffer subject, content;
		PreferenceManager preferenceManager;
		
		
		preferenceManager = (PreferenceManager) getServletContext().getAttribute("preferenceManager");
	
		subject = new StringBuffer();
		subject.append("Eingabeaufforderung | Storage Solution");
		
		content = new StringBuffer();
		content.append("FYI - Die Storage Solution wurde soeben gestarted.\r\n\r\n" +
						
						"Sofern du die Netzwerkfreigaben noch konfigurieren m�chtest, " +
						"klickst du auf den unten angef�hrten Link:\r\n" +
						"http://" + preferenceManager.getStorageServer().getIpAddress() + ":8080" + "/" + getServletContext().getServletContextName() + "\r\n\r\n" +
						
						"Weitere Vorgehensweise:\r\n" + 
						"1. Nach der Archivierung der Daten, Versand einer Erinnerungsmail\r\n" +
						"2. Download des Backups auf die lokale Platte\r\n" +
						"3. Archivierung des Backups auf DVD/CD mit lokaler Brennsoftware\r\n\r\n" +
							
						"Viel Erfolg und LG!");
		
		try {
			
			Mail.sendMail(subject, content,
					preferenceManager.getSender().getEmailAddress(),
					preferenceManager.getRecipient().getEmailAddress(), 
					preferenceManager.getSender().getSMTPServer(),
					preferenceManager.getSender().getEmailUsername(),
					preferenceManager.getSender().getEmailPassword());
			
		} catch (Exception ex) {
			System.out.println("No mail sent.");
		}
	}
	
	private void doBackup(String backupShellScript, String reportDirectory) {
		
		Calendar calendar = GregorianCalendar.getInstance();
		StringBuffer date = new StringBuffer();
		Env env = new ShellEnv();
		
		date.append(calendar.get(Calendar.YEAR) + "_");
		date.append(calendar.get(Calendar.MONTH) + "_");
		date.append(calendar.get(Calendar.DAY_OF_MONTH));
		
		env.exec("chmod 755 " + backupShellScript, true);
		env.exec(backupShellScript + " " + date.toString() + " " + reportDirectory, true);
		env.exec("shutdown -h now", false);
	}
}